using UnityEngine;

namespace Com.LuisPedroFonseca.ProCamera2D
{
	public class ProCamera2DSpeedBasedZoom : BasePC2D, ISizeDeltaChanger
	{
		public static string ExtensionName = "Speed Based Zoom";

		[Tooltip("The speed at which the camera will reach it's max zoom out.")]
		public float CamVelocityForZoomOut = 5f;

		[Tooltip("Below this speed the camera zooms in. Above this speed the camera will start zooming out.")]
		public float CamVelocityForZoomIn = 2f;

		[Tooltip("Represents how smooth the zoom in of the camera should be. The lower the number the quickest the zoom is. A number too low might cause some stuttering.")]
		public float ZoomInSpeed = 1f;

		[Tooltip("Represents how smooth the zoom out of the camera should be. The lower the number the quickest the zoom is. A number too low might cause some stuttering.")]
		public float ZoomOutSpeed = 1f;

		[Tooltip("Represents how smooth the zoom in of the camera should be. The lower the number the quickest the zoom is.")]
		[Range(0f, 3f)]
		public float ZoomInSmoothness = 1f;

		[Tooltip("Represents how smooth the zoom out of the camera should be. The lower the number the quickest the zoom is.")]
		[Range(0f, 3f)]
		public float ZoomOutSmoothness = 1f;

		[Tooltip("Represents the maximum amount the camera should zoom in when the camera speed is below SpeedForZoomIn")]
		public float MaxZoomInAmount = 2f;

		[Tooltip("Represents the maximum amount the camera should zoom out when the camera speed is equal to SpeedForZoomOut")]
		public float MaxZoomOutAmount = 2f;

		private float _zoomVelocity;

		private float _initialCamSize;

		private float _previousCamSize;

		private Vector3 _previousCameraPosition;

		private float _prevZoomAmount;

		[HideInInspector]
		public float CurrentVelocity;

		private int _sdcOrder = 1000;

		public int SDCOrder
		{
			get
			{
				return _sdcOrder;
			}
			set
			{
				_sdcOrder = value;
			}
		}

		protected override void Awake()
		{
			base.Awake();
			if (!(ProCamera2D == null))
			{
				_initialCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * 0.5f;
				_previousCamSize = _initialCamSize;
				_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
				_prevZoomAmount = 0f;
				ProCamera2D.AddSizeDeltaChanger(this);
			}
		}

		public float AdjustSize(float deltaTime, float originalDelta)
		{
			if (!base.enabled)
			{
				return originalDelta;
			}
			float num = 0f;
			if (_previousCamSize == ProCamera2D.ScreenSizeInWorldCoordinates.y)
			{
				_prevZoomAmount = 0f;
				_zoomVelocity = 0f;
			}
			CurrentVelocity = (_previousCameraPosition - VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition))).magnitude / deltaTime;
			_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
			if (CurrentVelocity > CamVelocityForZoomIn)
			{
				float value = (CurrentVelocity - CamVelocityForZoomIn) / (CamVelocityForZoomOut - CamVelocityForZoomIn);
				num = ZoomOutSpeed * Mathf.Clamp01(value);
			}
			else
			{
				float value2 = 1f - CurrentVelocity / CamVelocityForZoomIn;
				num = (0f - ZoomInSpeed) * Mathf.Clamp01(value2);
			}
			float num2 = Mathf.SmoothDamp(_prevZoomAmount, num * deltaTime, ref _zoomVelocity, (CurrentVelocity > CamVelocityForZoomIn) ? ZoomOutSmoothness : ZoomInSmoothness);
			float num3 = ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f + num2;
			float num4 = _initialCamSize / MaxZoomInAmount;
			float num5 = MaxZoomOutAmount * _initialCamSize;
			if (num3 < num4)
			{
				num2 -= num3 - num4;
			}
			else if (num3 > num5)
			{
				num2 -= num3 - num5;
			}
			_prevZoomAmount = num2;
			_previousCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y;
			return originalDelta + num2;
		}

		public override void OnReset()
		{
			_previousCamSize = _initialCamSize;
			_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
			_prevZoomAmount = 0f;
			_zoomVelocity = 0f;
		}
	}
}
